package com.lyc.api;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.lyc.constants.Constants;
import com.lyc.utils.HttpClient;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class KsApiClient {

    private static final Gson policyGson = new Gson();
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final String HOST = "https://u.kuaishou.com";

    public static String KS_APP_ID;
    public static Integer KS_ACCESS_KEY;
    public static String KS_SECURITY_KEY;

    static {
        loadProperties();
    }

    private static void loadProperties() {
        Properties props = new Properties();
        try (FileInputStream fis = new FileInputStream(new File(Constants.ACCOUNT_PATH + "account.properties"))) {
            props.load(fis);

            KS_APP_ID = String.valueOf(props.getProperty("KS_APP_ID"));
            KS_ACCESS_KEY = Integer.valueOf(props.getProperty("KS_ACCESS_KEY"));
            KS_SECURITY_KEY = String.valueOf(props.getProperty("KS_SECURITY_KEY"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建快手广告的通用方法。
     *
     * @param namePrefix 广告名称前缀
     * @param adStyle 广告样式
     * @param renderType 渲染类型
     * @param materialTypeList 材料类型列表
     * @param additionalParams 额外参数
     * @return 创建的广告ID
     */
    private static long createKsAd(String namePrefix, int adStyle, int renderType, List<Integer> materialTypeList, Map<String, Object> additionalParams) {
        Map<String, Object> params = new HashMap<>();
        params.put("appId", KS_APP_ID);
        params.put("name", namePrefix + "_" + LocalDateTime.now().format(DATE_FORMATTER));
        params.put("adStyle", adStyle);
        params.put("renderType", renderType);
        params.put("materialTypeList", materialTypeList);
        params.putAll(additionalParams);

        String url = generateQueryAppUrl("/api/position/add");

        // 发送HTTP请求
        String response = HttpClient.doPost(url, params);

        System.out.println("response = " + response);

        // 解析响应
        return parseResponse(response);
    }

    /**
     * 创建快手新插屏广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsNewInsertAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("templateId", 9);
        additionalParams.put("adRolloutSize", 3);
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrate", 1);

        return createKsAd("快手_新插屏", 23, 2, List.of(1, 2, 5, 6), additionalParams);
    }

    /**
     * 创建快手开屏广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsSplashAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("skipAdMode", 0);
        additionalParams.put("templateId", 1000);
        additionalParams.put("countdownShow", 1);
        additionalParams.put("voice", 1);
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrate", 1);

        return createKsAd("快手_开屏", 4, 2, List.of(1, 3), additionalParams);
    }

    /**
     * 创建快手draw视频广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsDrawAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("adStyle", 6);
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrate", 1);
        additionalParams.put("videoSoundType", 1);

        return createKsAd("快手_draw信息流", 6, 1, List.of(1), additionalParams);
    }

    /**
     * 创建快手全屏视频广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsFullscreenAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("adStyle", 3);
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrate", 1);

        return createKsAd("快手_全屏", 3, 1, List.of(1), additionalParams);
    }

    /**
     * 创建快手插屏广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsInsertAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("templateId", 9);
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrate", 1);

        return createKsAd("快手_插屏", 13, 2, List.of(1, 2, 5, 6), additionalParams);
    }

    /**
     * 创建快手激励视频广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsRewardAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("rewardedType", 1);
        additionalParams.put("rewardedNum", 1);
        additionalParams.put("callbackStatus", 1);
        additionalParams.put("callbackUrl", "https://quanminchangwan.kuhuanqiye.top/api/huitiao.houtai/huitiao?userId=__UID__&transId=__TRANSID__&sign=__SIGN__&amount=__RAMOUNT__&name=__RNAME__&extra=__EXTRA__");
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrate", 1);

        return createKsAd("快手_激励", 2, 1, List.of(1), additionalParams);
    }

    /**
     * 创建快手信息流广告。
     *
     * @return 创建的广告ID
     */
    public static long createKsNativeAd() {
        Map<String, Object> additionalParams = new HashMap<>();
        additionalParams.put("adStyle", 1);
        additionalParams.put("priceStrategy", 2);
        additionalParams.put("biddingStrategy", 1);

        List<Map<String, Integer>> multiTemplateParams = new ArrayList<>();
        for (int i : new int[]{1, 2, 3, 4, 5, 14, 15, 16, 17, 18, 19}) {
            Map<String, Integer> templateParam = new HashMap<>();
            templateParam.put("templateId", i);
            multiTemplateParams.add(templateParam);
        }
        additionalParams.put("multiTemplateParams", multiTemplateParams);

        return createKsAd("快手_信息流", 1, 2, List.of(1, 2, 5, 6), additionalParams);
    }

    /**
     * 解析响应数据。
     *
     * @param response HTTP响应字符串
     * @return 创建的广告ID或-1表示失败
     */
    private static long parseResponse(String response) {
        Type responseType = new TypeToken<Map<String, Object>>() {}.getType();
        Map<String, Object> responseMap = policyGson.fromJson(response, responseType);

        int code = ((Number) responseMap.get("result")).intValue();
        if (code == 1) {
            return ((Number) responseMap.get("data")).longValue();
        } else {
            System.out.println("Failed to create placement. Code: " + code);
            return -1;
        }
    }

    /**
     * 生成带签名的请求URL。
     *
     * @param requestUrl 请求路径
     * @return 完整的请求URL
     */
    public static String generateQueryAppUrl(String requestUrl) {
        if (requestUrl == null || requestUrl.isEmpty()) {
            throw new IllegalArgumentException("Request URL cannot be null or empty");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("ak", KS_ACCESS_KEY);
        params.put("sk", KS_SECURITY_KEY);
        params.put("timestamp", System.currentTimeMillis() / 1000);

        Map<String, Object> sortedParams = new TreeMap<>(params);
        String signingUrl = buildUrl(requestUrl, sortedParams);
        String sign = DigestUtils.md5Hex(signingUrl);

        sortedParams.put("sign", sign);
        sortedParams.remove("sk");

        return buildUrl(HOST + requestUrl, sortedParams);
    }

    /**
     * 构建URL。
     *
     * @param baseUrl 基础URL
     * @param params 参数列表
     * @return 构建的URL
     */
    private static String buildUrl(String baseUrl, Map<String, Object> params) {
        StringBuilder urlBuilder = new StringBuilder(baseUrl).append('?');
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            urlBuilder.append(entry.getKey())
                    .append('=')
                    .append(URLEncoder.encode(String.valueOf(entry.getValue()), StandardCharsets.UTF_8))
                    .append('&');
        }
        if (urlBuilder.charAt(urlBuilder.length() - 1) == '&') {
            urlBuilder.setLength(urlBuilder.length() - 1);
        }
        return urlBuilder.toString();
    }
}
